package parser

import (
	"bytes"
	"fmt"

	"vitess.io/vitess/go/vt/sqlparser"
)

func selectExprToField(expr sqlparser.SelectExpr) (*Field, error) {
	switch e := expr.(type) {
	case *sqlparser.AliasedExpr:
		f := &Field{}
		var buf bytes.Buffer
		err := exprToString(&buf, expr)
		if err != nil {
			return nil, err
		}
		f.SetExpr(buf.String())
		f.name = e.As.String()
		if f.name == "" {
			f.name = f.sql
		}
		return f, nil
	default:
		return nil, fmt.Errorf("unsupported syntax: %#v", e)
	}
}

func convertSelect(s *sqlparser.Select, query string) (Statement, error) {
	stmt := &SelectStatement{
		Columns: ColumnSet{},
	}
	stmt.sql = query
	if len(s.From) == 1 {
		t, ok := s.From[0].(*sqlparser.AliasedTableExpr)
		if ok {
			err := SQLNodeToColumns(stmt.Columns, s)
			if err != nil {
				return nil, err
			}
			stmt.tbl = t.Expr.(sqlparser.TableName).Name.String()
			fields := make([]*Field, len(s.SelectExprs))
			for i, e := range s.SelectExprs {
				field, err := selectExprToField(e)
				if err != nil {
					return nil, err
				}
				fields[i] = field
			}
			stmt.Fields = fields
			if s.Where != nil {
				where, err := whereToWhereExpr(s.Where)
				if err != nil {
					return nil, err
				}
				stmt.where = where
			}
		}
	}
	return stmt, nil
}

type SelectStatement struct {
	BaseStatement
	Fields  []*Field
	Columns ColumnSet
	tbl     string
	where   *WhereExpr
}

func (s *SelectStatement) IsDual() bool {
	return s.tbl == "dual"
}

func (s *SelectStatement) Table() string {
	return s.tbl
}

func (s *SelectStatement) Where() *WhereExpr {
	return s.where
}
